#include "rfid_board.h"
#include "rfid_protocol.h"
#include "key_conversion.h"

#if _RFID_FUNCTION_ENABLE_

/**
 * @brief 验证卡类型是否有效
 *
 * @param Type  - 卡类型
 * @return bool - 验证状态（true：有效 false：无效）
 */
static bool RfidVerifyCardTypeIsValid(uint8_t Type);

/**
 * @brief 验证报文有效性
 *
 * @param pDataIn  - 输入报文
 * @param SizeIn   - 报文长度
 * @return uint8_t - 累加计算值
 */
static uint8_t RfidCalculateSumCheck(const uint8_t *pDataIn, uint16_t SizeIn);

/**
 * @brief 计算给定数据的异或校验值
 *
 * @param pDataIn  - 指向数据的指针
 * @param SizeIn   - 数据的长度
 * @return uint8_t - 异或校验值
 */
static uint8_t RfidCalculateXorValue(const uint8_t *pDataIn, uint16_t SizeIn);

/**
 * @brief 验证分类是否有效
 *
 * @param TranslationCategory - 分类
 * @return bool               - 验证状态（true：有效 false：无效）
 */
static bool RfidVerifyTranslationCategoryValidity(uint16_t TranslationCategory);

/**
 * @brief 验证分组是否有效
 *
 * @param Grouping - 分组
 * @return bool    - 验证状态（true：有效 false：无效）
 */
static bool RfidVerifyGroupingValidity(uint32_t Grouping);

/**
 * @brief 验证房间信息有效性
 *
 * @param NumberOfRoom         - 房间数量
 * @param pCardRoomAttributeIn - 房源信息
 * @param GardenEn             - 园区验证标识
 * @param BuildEn              - 楼栋验证标识
 * @param FloorEn              - 楼层验证标识
 * @param RoomEn               - 房间号验证标志
 * @param SubRoomEn            - 子房间号验证标识
 * @return bool                - 验证状态（true：成功 false：失败）
 */
static bool RfidVerifyTheValidityOfRoomInformation(uint8_t NumberOfRoom, CardRoomAttribute_t *pCardRoomAttributeIn, bool GardenEn, bool BuildEn, bool FloorEn, bool RoomEn, bool SubRoomEn);

/**
 * @brief 核实授权时间
 *
 * @param StartTime          - 授权起始时间
 * @param EndTime            - 授权结束时间
 * @param Date               - 授权周期
 * @param pTimePeriodIn      - 时间段
 * @return bool              - 验证状态（true：成功 false：失败）
 */
static bool RfidVerificationOfAuthorisationTime(const uint32_t StartTime, const uint32_t EndTime, const uint8_t Date, CardCycleUnion_t *pTimePeriodIn);

/**
 * @brief 验证顶替信息
 *
 * @param StartTimestamp      - 起始时间戳
 * @param ReplaceId           - 顶替编码
 * @param CardType            - 卡类型
 * @return ReplaceErrorCode_t - 验证状态
 */
static ReplaceErrorCode_t RfidVerifyReplaceInformation(uint32_t ReplaceTime, uint16_t ReplaceId, OfflineCardType_t CardType);

/**
 * @brief 更新顶替信息
 *
 * @param ReplaceEn   - 顶替使能标识
 * @param ReplaceTime - 顶替时间
 * @param ReplaceId   - 顶替编码
 * @param CardType    - 卡类型
 */
static void RfidUpdateReplaceInformation(uint8_t ReplaceEn, uint32_t ReplaceTime, uint16_t ReplaceId, OfflineCardType_t CardType);

/**
 * @brief 重构离线卡数据
 *
 * @param pCardInfomation - 卡数据
 * @param pDataOut        - 重构后数据
 * @param pSizeOut        - 重构后数据长度
 * @return bool           - 重构状态（true：成功 false：失败）
 */
static bool RfidRefactorOfflineCardData(RfidProtocolFormat_t *pCardInfomation, uint8_t *pDataOut, uint16_t *pSizeOut);

/**
 * @brief 解析校时卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseCalibrationTimeCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析宾客卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseGuestRoomCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析总卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseMasterRoomCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析楼栋卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseBuildingCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析楼层卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseFloorCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析园区卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseParkCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析安装卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseInstallCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析虚拟卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseVirtualCardSerialNumberData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析恢复出厂卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseClearCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析常开卡数据
 *
 * @param pCardInfomationIn - 卡数据
 */
static void RfidPraseNormalOpenCardData(RfidProtocolFormat_t *pCardInfomationIn);

/**
 * @brief 解析重置卡数据
 *
 * @param pCardInfomationIn - 卡数据
 * @return bool             - 解析状态（true：成功 false：失败）
 */
static bool RfidPraseResetCardData(RfidProtocolFormat_t *pCardInfomationIn);

const OfflineCardPrase_t OfflineCardPrase[] = {
    [RFID_PARK_CARD] = RfidPraseParkCardData,
    [RFID_CLEAR_CARD] = RfidPraseClearCardData,
    [RFID_FLOOR_CARD] = RfidPraseFloorCardData,
    [RFID_INSTALL_CARD] = RfidPraseInstallCardData,
    [RFID_BUILDING_CARD] = RfidPraseBuildingCardData,
    [RFID_GUEST_ROOM_CARD] = RfidPraseGuestRoomCardData,
    [RFID_MASTER_ROOM_CARD] = RfidPraseMasterRoomCardData,
    [RFID_NORMAL_OPEN_CARD] = RfidPraseNormalOpenCardData,
    [RFID_CALIBRATION_TIME_CARD] = RfidPraseCalibrationTimeCardData,
    [RFID_VIRTUAL_CARD_SERIAL_NUMBER] = RfidPraseVirtualCardSerialNumberData,
};

const OfflineCardDataUpdate_t OfflineCardDataUpdate[] = {
    [RFID_CLEAR_CARD] = RfidPraseResetCardData,
};

static bool
RfidVerifyCardTypeIsValid(uint8_t Type)
{
  switch (Type)
  {
  case RFID_PARK_CARD:
  case RFID_CLEAR_CARD:
  case RFID_FLOOR_CARD:
  case RFID_INSTALL_CARD:
  case RFID_BUILDING_CARD:
  case RFID_GUEST_ROOM_CARD:
  case RFID_NORMAL_OPEN_CARD:
  case RFID_MASTER_ROOM_CARD:
  case RFID_CALIBRATION_TIME_CARD:
  case RFID_VIRTUAL_CARD_SERIAL_NUMBER:
    return true;
  }

  return false;
}

static uint8_t RfidCalculateSumCheck(const uint8_t *pDataIn, uint16_t SizeIn)
{
  uint32_t SumVal = 0;

  for (uint16_t i = 0; i < SizeIn; i++)
  {
    SumVal += pDataIn[i];
  }

  return (uint8_t)(SumVal & 0x000000FF);
}

static uint8_t RfidCalculateXorValue(const uint8_t *pDataIn, uint16_t SizeIn)
{
  uint8_t XorValue = 0;

  for (uint16_t i = 0; i < SizeIn; i++)
  {
    XorValue ^= pDataIn[i];
  }

  return XorValue;
}

static bool RfidVerifyTranslationCategoryValidity(uint16_t TranslationCategory)
{
  uint16_t TranslationCategoryId = RfidGetRoomType();

  if ((TranslationCategoryId != 0) && (TranslationCategoryId & TranslationCategory))
    return true;

  return false;
}

static bool RfidVerifyGroupingValidity(uint32_t Grouping)
{
  uint32_t GroupingId = RfidGetGroupingNumber();

  if ((GroupingId != 0) && (GroupingId & Grouping))
    return true;

  return false;
}

static bool RfidVerifyTheValidityOfRoomInformation(uint8_t NumberOfRoom, CardRoomAttribute_t *pCardRoomAttributeIn, bool GardenEn, bool BuildEn, bool FloorEn, bool RoomEn, bool SubRoomEn)
{
  if (pCardRoomAttributeIn != NULL)
  {
#if ((_BOARD_TYPE_ & _DA01_BOARD_) == _DA01_BOARD_)
    if (NumberOfRoom == 0)
      return true;
#endif

    uint32_t RoomId = RfidGetRoomNumber();
    uint8_t BuildId = RfidGetBuildNumber();
    uint8_t FloorId = RfidGetFloorNumber();
    uint8_t GardenId = RfidGetGardenNumber();
    uint8_t SubroomId = RfidGetChildRommNumber();

    // 验证门锁归属地
    {
      if (SubroomId == 0)
      {
        SubRoomEn = false;

        if (RoomId == 0)
        {
          RoomEn = false;

          if (FloorId == 0)
          {
            FloorEn = false;

            if (BuildId == 0)
            {
              BuildEn = false;

              if (GardenId == 0)
              {
                GardenEn = false;
              }
            }
          }
        }
      }
    }

    // 验证卡片权限
    {
      for (uint8_t DeviceInfo = 0; DeviceInfo < NumberOfRoom; DeviceInfo++)
      {
        if ((pCardRoomAttributeIn[DeviceInfo].GardenId == GardenId) || (GardenEn == false))
        {
          if ((pCardRoomAttributeIn[DeviceInfo].BuildId == BuildId) || (BuildEn == false))
          {
            if ((pCardRoomAttributeIn[DeviceInfo].FloorId == FloorId) || (FloorEn == false))
            {
              if ((pCardRoomAttributeIn[DeviceInfo].RoomId == RoomId) || (RoomEn == false))
              {
                if ((pCardRoomAttributeIn[DeviceInfo].SubroomId == SubroomId) || (SubRoomEn == false) || (pCardRoomAttributeIn[DeviceInfo].SubroomId == 0))
                  return true;
              }
            }
          }
        }
      }
    }
  }

  return false;
}

static bool RfidVerificationOfAuthorisationTime(const uint32_t StartTime, const uint32_t EndTime, const uint8_t Date, CardCycleUnion_t *pTimePeriodIn)
{
  uint8_t Week = 0, Hour = 0, Minute = 0;
  CardCycleUnion_t *pCardCycleUnion = NULL;
  uint32_t StartTimestamp = 0, EndTimestamp = 0, NowTimestamp = 0;
  uint16_t AllowableTimeError = (uint16_t)(RfidGetAllowableTimeError() * 60);

  if (pTimePeriodIn != NULL)
  {
    if (EndTime > StartTime)
    {
      NowTimestamp = RfidGetTimestamp();
      StartTimestamp = (AllowableTimeError < StartTime) ? (StartTime - AllowableTimeError) : StartTime;
      EndTimestamp = ((UINT32_MAX - AllowableTimeError) >= EndTime) ? (EndTime + AllowableTimeError) : EndTime;
      PRINT("[rfid]: now timestamp: %d, start timestamp: %d, end timestamp: %d.\r\n", NowTimestamp, StartTimestamp, EndTimestamp);

      if ((StartTimestamp <= NowTimestamp) || (RfidGetValidationStartTimeEnableFlag() == false))
      {
        if (EndTimestamp >= NowTimestamp)
        {
          RfidGetTheCurrentTime(NULL, NULL, NULL, &Hour, &Minute, NULL, &Week);

          if ((Date == 0) || (Date & (1 << Week)))
          {
            // 验证时间段是否为空
            {
              uint8_t TimePeriod = 0;

              for (TimePeriod = 0; TimePeriod < OFFLINE_CARD_MAX_TIME_SLOTS; TimePeriod++)
              {
                if (pTimePeriodIn[TimePeriod].BasicCycle != 0)
                  break;
              }

              if (TimePeriod >= OFFLINE_CARD_MAX_TIME_SLOTS)
                return true;
            }

            // 验证时间段是否有效
            {
              for (uint8_t i = 0; i < OFFLINE_CARD_MAX_TIME_SLOTS; i++)
              {
                pCardCycleUnion = &pTimePeriodIn[i];
                if (pCardCycleUnion->BasicCycle != 0)
                {
                  NowTimestamp = (Hour * 60) + Minute;
                  EndTimestamp = (pCardCycleUnion->TimeCycle.EndHour * 60) + pCardCycleUnion->TimeCycle.EndMinute;
                  StartTimestamp = (pCardCycleUnion->TimeCycle.StartHour * 60) + pCardCycleUnion->TimeCycle.StartMinute;

                  if (EndTimestamp <= StartTimestamp)
                  {
                    EndTimestamp += 24 * 60;
                  }

                  if (NowTimestamp < StartTimestamp)
                  {
                    NowTimestamp += 24 * 60;
                  }

                  if ((NowTimestamp >= StartTimestamp) && (NowTimestamp < EndTimestamp))
                    return true;
                }
              }
            }
          }
        }
      }
    }
  }

  return false;
}

static ReplaceErrorCode_t RfidVerifyReplaceInformation(uint32_t ReplaceTime, uint16_t ReplaceId, OfflineCardType_t CardType)
{
#if ((_BOARD_TYPE_ & _DA01_BOARD_) == _DA01_BOARD_)
  return RFID_PROTOCOL_SUCCESS;

#else
  switch (CardType)
  {
  case RFID_PARK_CARD:
  {
    if (ReplaceTime < RfidGetParkCardReplaceTime())
      return RFID_PROTOCOL_TIME_ERROR;

    if (ReplaceId < RfidGetParkCardReplaceId())
      return RFID_PROTOCOL_ID_ERROR;
  }
  break;

  case RFID_FLOOR_CARD:
  {
    if (ReplaceTime < RfidGetFloorCardReplaceTime())
      return RFID_PROTOCOL_TIME_ERROR;

    if (ReplaceId < RfidGetFloorCardReplaceId())
      return RFID_PROTOCOL_ID_ERROR;
  }
  break;

  case RFID_BUILDING_CARD:
  {
    if (ReplaceTime < RfidGetBuildCardReplaceTime())
      return RFID_PROTOCOL_TIME_ERROR;

    if (ReplaceId < RfidGetBuildCardReplaceId())
      return RFID_PROTOCOL_ID_ERROR;
  }
  break;

  case RFID_GUEST_ROOM_CARD:
  {
    RfidCardProtocol_t CardProtocol = RfidGetCardReadingProtocol();
    if (CardProtocol == RFID_CARD_PROTOCOL_HZ)
    {
      if (ReplaceId == 0)
      {
        if (ReplaceTime < RfidGetGuestCardReplaceTime())
          return RFID_PROTOCOL_TIME_ERROR;
      }

      if (ReplaceId == RfidGetGuestCardReplaceId())
        return RFID_PROTOCOL_SUCCESS;

      if (ReplaceTime < RfidGetGuestCardReplaceTime())
        return RFID_PROTOCOL_TIME_ERROR;
    }
    else
    {
      if (ReplaceId == 0)
      {
        if (ReplaceTime >= RfidGetGuestCardReplaceTime())
          return RFID_PROTOCOL_SUCCESS;
      }

      if (ReplaceTime < RfidGetGuestCardReplaceTime())
        return RFID_PROTOCOL_TIME_ERROR;

      if (ReplaceId < RfidGetGuestCardReplaceId())
        return RFID_PROTOCOL_ID_ERROR;
    }
  }
  break;

  case RFID_MASTER_ROOM_CARD:
  {
    if (ReplaceTime < RfidGetMasterCardReplaceTime())
      return RFID_PROTOCOL_TIME_ERROR;

    if (ReplaceId < RfidGetMasterCardReplaceId())
      return RFID_PROTOCOL_ID_ERROR;
  }
  break;

  case RFID_NORMAL_OPEN_CARD:
  {
    if (ReplaceTime < RfidGetNormalOpenCardReplaceTime())
      return RFID_PROTOCOL_TIME_ERROR;

    if (ReplaceId < RfidGetNormalOpenCardReplaceId())
      return RFID_PROTOCOL_ID_ERROR;
  }
  break;

  default:
    break;
  }

  return RFID_PROTOCOL_SUCCESS;
#endif
}

static void RfidUpdateReplaceInformation(uint8_t ReplaceEn, uint32_t ReplaceTime, uint16_t ReplaceId, OfflineCardType_t CardType)
{
#if ((_BOARD_TYPE_ & _DA01_BOARD_) == _DA01_BOARD_)
  return;

#else
  switch (CardType)
  {
  case RFID_PARK_CARD:
  {
    if ((ReplaceEn == true) || (ReplaceId > RfidGetParkCardReplaceId()))
    {
      if (ReplaceEn == true)
      {
        RfidSetParkCardReplaceTime(ReplaceTime);
      }

      RfidSetParkCardReplaceId(ReplaceId);
      RfidUpdateDeviceParameters();
    }
  }
  break;

  case RFID_FLOOR_CARD:
  {
    if ((ReplaceEn == true) || (ReplaceId > RfidGetFloorCardReplaceId()))
    {
      if (ReplaceEn == true)
      {
        RfidSetFloorCardReplaceTime(ReplaceTime);
      }

      RfidSetFloorCardReplaceId(ReplaceId);
      RfidUpdateDeviceParameters();
    }
  }
  break;

  case RFID_BUILDING_CARD:
  {
    if ((ReplaceEn == true) || (ReplaceId > RfidGetBuildCardReplaceId()))
    {
      if (ReplaceEn == true)
      {
        RfidSetBuildCardReplaceTime(ReplaceTime);
      }

      RfidSetBuildCardReplaceId(ReplaceId);
      RfidUpdateDeviceParameters();
    }
  }
  break;

  case RFID_GUEST_ROOM_CARD:
  {
    RfidCardProtocol_t CardProtocol = RfidGetCardReadingProtocol();
    if (CardProtocol == RFID_CARD_PROTOCOL_HZ)
    {
      uint16_t OldReplaceId = 0;
      uint32_t OldReplaceTime = 0;
      bool UpdateReplaceFlag = false;

      if (ReplaceId != 0)
      {
        OldReplaceId = RfidGetGuestCardReplaceId();

        if (OldReplaceId != ReplaceId)
        {
          OldReplaceTime = RfidGetGuestCardReplaceTime();
          if (OldReplaceTime < ReplaceTime)
          {
            UpdateReplaceFlag = true;
          }
        }
      }
      else
      {
        if (ReplaceEn == true)
        {
          UpdateReplaceFlag = true;
        }
      }

      if (UpdateReplaceFlag == true)
      {
        if (ReplaceId != 0)
        {
          RfidSetGuestCardReplaceId(ReplaceId);
        }

        RfidSetGuestCardReplaceTime(ReplaceTime);
        RfidUpdateDeviceParameters();
      }
    }
    else
    {
      if ((ReplaceEn == true) || (ReplaceId > RfidGetGuestCardReplaceId()))
      {
        if (ReplaceEn == true)
        {
          RfidSetGuestCardReplaceTime(ReplaceTime);
        }

        if (ReplaceId != 0)
        {
          RfidSetGuestCardReplaceId(ReplaceId);
        }

        RfidUpdateDeviceParameters();
      }
    }
  }
  break;

  case RFID_MASTER_ROOM_CARD:
  {
    if ((ReplaceEn == true) || (ReplaceId > RfidGetMasterCardReplaceId()))
    {
      if (ReplaceEn == true)
      {
        RfidSetMasterCardReplaceTime(ReplaceTime);
      }

      RfidSetMasterCardReplaceId(ReplaceId);
      RfidUpdateDeviceParameters();
    }
  }
  break;

  case RFID_NORMAL_OPEN_CARD:
  {
    if ((ReplaceEn == true) || (ReplaceId > RfidGetNormalOpenCardReplaceId()))
    {
      if (ReplaceEn == true)
      {
        RfidSetNormalOpenCardReplaceTime(ReplaceTime);
      }

      RfidSetNormalOpenCardReplaceId(ReplaceId);
      RfidUpdateDeviceParameters();
    }
  }
  break;

  default:
    break;
  }
#endif
}

static bool RfidRefactorOfflineCardData(RfidProtocolFormat_t *pCardInfomation, uint8_t *pDataOut, uint16_t *pSizeOut)
{
  if ((pCardInfomation != NULL) && (pDataOut != NULL) && (pSizeOut != NULL))
  {
    uint16_t DataLength = 0;
    uint8_t CardData[RFID_MAX_LENGTH_OF_OPERATION_DATA] = {0};

    {
      memcpy(&CardData[DataLength], pCardInfomation->Random, OFFLINE_CARD_RANDOM_BIT_LENGTH);
      DataLength += OFFLINE_CARD_RANDOM_BIT_LENGTH;
      memcpy(&CardData[DataLength], &pCardInfomation->Captcha, OFFLINE_CARD_CAPTCHA_BIT_LENGTH);
      DataLength += OFFLINE_CARD_CAPTCHA_BIT_LENGTH;
      CardData[DataLength++] = pCardInfomation->CardType;
      CardData[DataLength++] = (uint16_t)((pCardInfomation->ReplaceId & 0xFF00) >> 8);
      CardData[DataLength++] = (uint16_t)(pCardInfomation->ReplaceId & 0x00FF);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->TranslationCategory & 0xFF00) >> 8);
      CardData[DataLength++] = (uint16_t)(pCardInfomation->TranslationCategory & 0x00FF);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->Grouping & 0xFF00) >> 8);
      CardData[DataLength++] = (uint16_t)(pCardInfomation->Grouping & 0x00FF);
      memset(&CardData[DataLength], 0, 4);
      DataLength += 4;
      CardData[DataLength++] = (uint16_t)((pCardInfomation->StartTimestamp & 0xFF000000) >> 24);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->StartTimestamp & 0x00FF0000) >> 16);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->StartTimestamp & 0x0000FF00) >> 8);
      CardData[DataLength++] = (uint16_t)(pCardInfomation->StartTimestamp & 0x000000FF);

      CardData[DataLength++] = (uint16_t)((pCardInfomation->EndTimestamp & 0xFF000000) >> 24);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->EndTimestamp & 0x00FF0000) >> 16);
      CardData[DataLength++] = (uint16_t)((pCardInfomation->EndTimestamp & 0x0000FF00) >> 8);
      CardData[DataLength++] = (uint16_t)(pCardInfomation->EndTimestamp & 0x000000FF);
      CardData[DataLength++] = pCardInfomation->Date;
      CardData[DataLength++] = pCardInfomation->NumberOfTimeSlots;
      for (uint8_t i = 0; i < pCardInfomation->NumberOfTimeSlots; i++)
      {
        CardData[DataLength++] = pCardInfomation->Time->TimeCycle.StartHour;
        CardData[DataLength++] = pCardInfomation->Time->TimeCycle.StartMinute;
        CardData[DataLength++] = pCardInfomation->Time->TimeCycle.EndHour;
        CardData[DataLength++] = pCardInfomation->Time->TimeCycle.EndMinute;
      }
      CardData[DataLength++] = pCardInfomation->CardFunction.Ident;
      CardData[DataLength++] = pCardInfomation->NumberOfRoom;
      for (uint8_t i = 0; i < pCardInfomation->NumberOfRoom; i++)
      {
        CardData[DataLength++] = pCardInfomation->RoomId[i].GardenId;
        CardData[DataLength++] = pCardInfomation->RoomId[i].BuildId;
        CardData[DataLength++] = pCardInfomation->RoomId[i].FloorId;
        CardData[DataLength++] = (uint8_t)((pCardInfomation->RoomId[i].RoomId & 0xFF000000) >> 24);
        CardData[DataLength++] = (uint8_t)((pCardInfomation->RoomId[i].RoomId & 0x00FF0000) >> 16);
        CardData[DataLength++] = (uint8_t)((pCardInfomation->RoomId[i].RoomId & 0x0000FF00) >> 8);
        CardData[DataLength++] = (uint8_t)(pCardInfomation->RoomId[i].RoomId & 0x000000FF);
        CardData[DataLength++] = pCardInfomation->RoomId[i].SubroomId;
      }
    }

    {
      uint16_t EncryptedDataLength = 0;
      uint8_t EncryptKeyValue[RFID_MAX_NUMBER_OF_CODED_TEXT + 1] = {0};

      // XOR 加密
      {
        EncryptedDataLength = DataLength - 4;
        memcpy(EncryptKeyValue, pCardInfomation->Random, OFFLINE_CARD_RANDOM_BIT_LENGTH);
        RfidCalXorEncrypt(EncryptKeyValue, OFFLINE_CARD_RANDOM_BIT_LENGTH, &CardData[4], EncryptedDataLength);
      }

      // AES 加密
      {
        EncryptedDataLength = DataLength;
        if ((EncryptedDataLength % 16) != 0)
        {
          EncryptedDataLength += (16 - (EncryptedDataLength % 16));
        }

        uint8_t *pDataBuffOffset = CardData, *pDataBuffOutOffset = pDataOut + 2;
        memcpy(EncryptKeyValue, RFID_KEY_FILL_WPRD_YJ, RFID_MAX_NUMBER_OF_CODED_TEXT);
        for (uint8_t i = 0; i < EncryptedDataLength / 16; i++)
        {
          RfidAesEcbEncrypt(EncryptKeyValue, pDataBuffOffset, pDataBuffOutOffset);

          pDataBuffOffset += 16;
          pDataBuffOutOffset += 16;
        }
      }

      // 填充固定参数
      {
        EncryptedDataLength += 3;
        pDataOut[0] = (uint8_t)((EncryptedDataLength & 0xFF00) >> 8);
        pDataOut[1] = (uint8_t)(EncryptedDataLength & 0x00FF);
        pDataOut[EncryptedDataLength - 1] = RfidCalculateSumCheck(pDataOut, EncryptedDataLength - 1);

        *pSizeOut = EncryptedDataLength;
      }
    }

    return true;
  }

  return false;
}

static void RfidPraseCalibrationTimeCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  bool SetStatus = false;

  if (pCardInfomationIn != NULL)
  {
    if (RfidSetTimeZone(pCardInfomationIn->Date) == true)
    {
      if (RfidUpdateRealTime(pCardInfomationIn->StartTimestamp) == true)
      {
        SetStatus = true;
        RfidUpdateDeviceParameters();
      }
    }

    RfidPlaySettingStatusAudio(SetStatus);
    OfflineCardOperationStatus_t OperationStatus = (SetStatus == true) ? OFFLINE_CARD_AUTHENTICATION_SUCCESS : OFFLINE_CARD_AUTHECTICATION_ERROR;
    RfidWriteCalibrationCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OperationStatus);
  }
}

static void RfidPraseGuestRoomCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetGuestCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        if ((RfidVerifyGroupingValidity(pCardInfomationIn->Grouping) == true) ||
            (RfidVerifyTranslationCategoryValidity(pCardInfomationIn->TranslationCategory) == true) ||
            (RfidVerifyTheValidityOfRoomInformation(pCardInfomationIn->NumberOfRoom, pCardInfomationIn->RoomId, true, true, true, true, true) == true))
        {
          ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_GUEST_ROOM_CARD);
          if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
          {
            bool ValidityResult = true;

            if (RfidGetDoubleLockEn() == true)
            {
              if ((RfidGetAllowedToOpenDoubleLock() != true) &&
                  (pCardInfomationIn->CardFunction.ControlBit.Recover != true))
              {
                ValidityResult = false;
              }
            }

            if (ValidityResult == true)
            {
              RfidUpdateReplaceInformation(pCardInfomationIn->CardFunction.ControlBit.Replace, pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_GUEST_ROOM_CARD);

              if (pCardInfomationIn->CardFunction.ControlBit.ClearEn != true)
              {
                RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }
              else
              {
                RfidWriteClearCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }

              PRINT("[rfid]: guest room card validation success.\r\n");
              RfidHintAuthenticationSuccessHanlder(RFID_GUEST_ROOM_CARD, pCardInfomationIn->CardSerialNumber, pCardInfomationIn->CardFunction.ControlBit.NormalOpen);
            }
            else
            {
              PRINT("[rfid]: equipment anti-lock.\r\n");

              RfidHintAntiLockHandler();
              RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
            }
          }
          else
          {
            PRINT("[rfid]: replace info error.\r\n");

            (ReplaceErrorCode == RFID_PROTOCOL_ID_ERROR) ? RfidHintCardRepaceErrorHandler() : RfidHintCardOutOfDateHanlder();
            RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
          }
        }
        else
        {
          PRINT("[rfid]: failure to verify room information.\r\n");

          RfidCardAffiliationErrorHanlder();
          RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
        RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_OUT_OF_DATE);
      }
    }
    else
    {
      PRINT("[rfid]: guest room card is not enabled.\r\n");

      RfidThisFunctionCardHasBeenDisabledHanlder();
      RfidWriteGuestCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
    }
  }
}

static void RfidPraseMasterRoomCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetMasterCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_MASTER_ROOM_CARD);
        if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
        {
          if ((pCardInfomationIn->CardFunction.ControlBit.Replace == true) || (pCardInfomationIn->ReplaceId > RfidGetMasterCardReplaceId()))
          {
            if (pCardInfomationIn->CardFunction.ControlBit.Replace == true)
            {
              RfidSetMasterCardReplaceTime(pCardInfomationIn->StartTimestamp);
            }
            else
            {
              RfidSetMasterCardReplaceId(pCardInfomationIn->ReplaceId);
            }

            RfidUpdateDeviceParameters();
          }

          if (pCardInfomationIn->CardFunction.ControlBit.ClearEn != true)
          {
            RfidWriteMasterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
          }
          else
          {
            RfidWriteClearCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
          }

          PRINT("[rfid]: master room card validation success.\r\n");
          RfidHintAuthenticationSuccessHanlder(RFID_MASTER_ROOM_CARD, pCardInfomationIn->CardSerialNumber, pCardInfomationIn->CardFunction.ControlBit.NormalOpen);
        }
        else
        {
          PRINT("[rfid]: replace info error.\r\n");

          (ReplaceErrorCode == RFID_PROTOCOL_ID_ERROR) ? RfidHintCardRepaceErrorHandler() : RfidHintCardOutOfDateHanlder();
          RfidWriteMasterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
        RfidWriteMasterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_OUT_OF_DATE);
      }
    }
    else
    {
      PRINT("[rfid]: master room card is not enabled.\r\n");

      RfidThisFunctionCardHasBeenDisabledHanlder();
      RfidWriteMasterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
    }
  }
}

static void RfidPraseBuildingCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetBuildCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        if ((RfidVerifyGroupingValidity(pCardInfomationIn->Grouping) == true) ||
            (RfidVerifyTranslationCategoryValidity(pCardInfomationIn->TranslationCategory) == true) ||
            (RfidVerifyTheValidityOfRoomInformation(pCardInfomationIn->NumberOfRoom, pCardInfomationIn->RoomId, true, true, false, false, false) == true))
        {
          ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_BUILDING_CARD);
          if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
          {
            bool ValidityResult = true;

            if (RfidGetDoubleLockEn() == true)
            {
              if ((RfidGetAllowedToOpenDoubleLock() != true) &&
                  (pCardInfomationIn->CardFunction.ControlBit.Recover != true))
              {
                ValidityResult = false;
              }
            }

            if (ValidityResult == true)
            {
              RfidUpdateReplaceInformation(pCardInfomationIn->CardFunction.ControlBit.Replace, pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_BUILDING_CARD);

              if (pCardInfomationIn->CardFunction.ControlBit.ClearEn != true)
              {
                RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }
              else
              {
                RfidWriteClearCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }

              PRINT("[rfid]: master build room card validation success.\r\n");
              RfidHintAuthenticationSuccessHanlder(RFID_BUILDING_CARD, pCardInfomationIn->CardSerialNumber, pCardInfomationIn->CardFunction.ControlBit.NormalOpen);
            }
            else
            {
              PRINT("[rfid]: equipment anti-lock.\r\n");

              RfidHintAntiLockHandler();
              RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
            }
          }
          else
          {
            PRINT("[rfid]: replace info error.\r\n");

            (ReplaceErrorCode == RFID_PROTOCOL_ID_ERROR) ? RfidHintCardRepaceErrorHandler() : RfidHintCardOutOfDateHanlder();
            RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
          }
        }
        else
        {
          PRINT("[rfid]: failure to verify room information.\r\n");

          RfidCardAffiliationErrorHanlder();
          RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
        RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_OUT_OF_DATE);
      }
    }
    else
    {
      PRINT("[rfid]: master build room card is not enabled.\r\n");

      RfidThisFunctionCardHasBeenDisabledHanlder();
      RfidWriteBuildCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
    }
  }
}

static void RfidPraseFloorCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetFloorCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        if ((RfidVerifyGroupingValidity(pCardInfomationIn->Grouping) == true) ||
            (RfidVerifyTranslationCategoryValidity(pCardInfomationIn->TranslationCategory) == true) ||
            (RfidVerifyTheValidityOfRoomInformation(pCardInfomationIn->NumberOfRoom, pCardInfomationIn->RoomId, true, true, true, false, false) == true))
        {
          ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_FLOOR_CARD);
          if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
          {
            bool ValidityResult = true;

            if (RfidGetDoubleLockEn() == true)
            {
              if ((RfidGetAllowedToOpenDoubleLock() != true) &&
                  (pCardInfomationIn->CardFunction.ControlBit.Recover != true))
              {
                ValidityResult = false;
              }
            }

            if (ValidityResult == true)
            {
              RfidUpdateReplaceInformation(pCardInfomationIn->CardFunction.ControlBit.Replace, pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_FLOOR_CARD);

              if (pCardInfomationIn->CardFunction.ControlBit.ClearEn != true)
              {
                RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }
              else
              {
                RfidWriteClearCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }

              PRINT("[rfid]: master floor room card validation success.\r\n");
              RfidHintAuthenticationSuccessHanlder(RFID_FLOOR_CARD, pCardInfomationIn->CardSerialNumber, pCardInfomationIn->CardFunction.ControlBit.NormalOpen);
            }
            else
            {
              PRINT("[rfid]: equipment anti-lock.\r\n");

              RfidHintAntiLockHandler();
              RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
            }
          }
          else
          {
            PRINT("[rfid]: replace time error.\r\n");

            RfidHintCardRepaceErrorHandler();
            RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
          }
        }
        else
        {
          PRINT("[rfid]: failure to verify room information.\r\n");

          RfidCardAffiliationErrorHanlder();
          RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
        RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_OUT_OF_DATE);
      }
    }
    else
    {
      PRINT("[rfid]: master floor room card is not enabled.\r\n");

      RfidThisFunctionCardHasBeenDisabledHanlder();
      RfidWriteFloorCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
    }
  }
}

static void RfidPraseParkCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetParkCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        if ((RfidVerifyGroupingValidity(pCardInfomationIn->Grouping) == true) ||
            (RfidVerifyTranslationCategoryValidity(pCardInfomationIn->TranslationCategory) == true) ||
            (RfidVerifyTheValidityOfRoomInformation(pCardInfomationIn->NumberOfRoom, pCardInfomationIn->RoomId, true, false, false, false, false) == true))
        {
          ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_PARK_CARD);
          if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
          {
            bool ValidityResult = true;

            if (RfidGetDoubleLockEn() == true)
            {
              if ((RfidGetAllowedToOpenDoubleLock() != true) &&
                  (pCardInfomationIn->CardFunction.ControlBit.Recover != true))
              {
                ValidityResult = false;
              }
            }

            if (ValidityResult == true)
            {
              RfidUpdateReplaceInformation(pCardInfomationIn->CardFunction.ControlBit.Replace, pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_PARK_CARD);

              if (pCardInfomationIn->CardFunction.ControlBit.ClearEn != true)
              {
                RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }
              else
              {
                RfidWriteClearCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
              }

              PRINT("[rfid]: master park room card validation success.\r\n");
              RfidHintAuthenticationSuccessHanlder(RFID_PARK_CARD, pCardInfomationIn->CardSerialNumber, pCardInfomationIn->CardFunction.ControlBit.NormalOpen);
            }
            else
            {
              PRINT("[rfid]: equipment anti-lock.\r\n");

              RfidHintAntiLockHandler();
              RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
            }
          }
          else
          {
            PRINT("[rfid]: replace info error.\r\n");

            (ReplaceErrorCode == RFID_PROTOCOL_ID_ERROR) ? RfidHintCardRepaceErrorHandler() : RfidHintCardOutOfDateHanlder();
            RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
          }
        }
        else
        {
          PRINT("[rfid]: failure to verify room information.\r\n");

          RfidCardAffiliationErrorHanlder();
          RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
        RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_OUT_OF_DATE);
      }
    }
    else
    {
      PRINT("[rfid]: master park room card is not enabled.\r\n");

      RfidThisFunctionCardHasBeenDisabledHanlder();
      RfidWriteParkCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
    }
  }
}

static void RfidPraseInstallCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
}

static void RfidPraseVirtualCardSerialNumberData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    RfidVerifyVirtualCardValidity(pCardInfomationIn->CardSerialNumber);
  }
}

static void RfidPraseClearCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  bool SetStatus = false;

  if (pCardInfomationIn != NULL)
  {
    if (pCardInfomationIn->CardFunction.Ident == 0)
    {
      SetStatus = true;
      RfidStartDeviceFactorySetting();
    }
    else
    {
      PRINT("[rfid]: card function: %02X.\r\n", pCardInfomationIn->CardFunction.Ident);

      if (pCardInfomationIn->CardFunction.ClearBit.ReplaceInfo == true)
      {
        SetStatus = true;

        RfidSetParkCardReplaceId(0);
        RfidSetBuildCardReplaceId(0);
        RfidSetFloorCardReplaceId(0);
        RfidSetGuestCardReplaceId(0);
        RfidSetMasterCardReplaceId(0);
        RfidSetNormalOpenCardReplaceId(0);

        RfidSetParkCardReplaceTime(0);
        RfidSetBuildCardReplaceTime(0);
        RfidSetFloorCardReplaceTime(0);
        RfidSetGuestCardReplaceTime(0);
        RfidSetMasterCardReplaceTime(0);
        RfidSetNormalOpenCardReplaceTime(0);

        RfidUpdateDeviceParameters();
        PRINT("[info]: clear all replace time success.\r\n");
      }

      if (pCardInfomationIn->CardFunction.ClearBit.Cardholder == true)
      {
        SetStatus = true;

        RfidDeleteAllCardholderInformation();
        PRINT("[info]: clear all cardholder success.\r\n");
      }

      if (pCardInfomationIn->CardFunction.ClearBit.Log == true)
      {
        SetStatus = true;

        RfidDeleteAllLoGInformation();
        PRINT("[info]: clear all log success.\r\n");
      }
    }

    if (SetStatus == true)
    {
      RfidWriteClearParameterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
      RfidPlaySettingStatusAudio(SetStatus);
    }
    else
    {
      RfidWriteClearParameterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);
      RfidPlaySettingStatusAudio(SetStatus);
    }
  }
}

static void RfidPraseNormalOpenCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  if (pCardInfomationIn != NULL)
  {
    if (RfidGetNormalOpenCardEn() == true)
    {
      if (RfidVerificationOfAuthorisationTime(pCardInfomationIn->StartTimestamp, pCardInfomationIn->EndTimestamp, pCardInfomationIn->Date, pCardInfomationIn->Time) == true)
      {
        if ((RfidVerifyGroupingValidity(pCardInfomationIn->Grouping) == true) ||
            (RfidVerifyTranslationCategoryValidity(pCardInfomationIn->TranslationCategory) == true) ||
            ((RfidVerifyTheValidityOfRoomInformation(pCardInfomationIn->NumberOfRoom, pCardInfomationIn->RoomId, true, true, true, true, true) == true) || (pCardInfomationIn->NumberOfRoom == 0)))
        {
          ReplaceErrorCode_t ReplaceErrorCode = RfidVerifyReplaceInformation(pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_NORMAL_OPEN_CARD);
          if (ReplaceErrorCode == RFID_PROTOCOL_SUCCESS)
          {
            bool ValidityResult = true;

            if (RfidGetDoubleLockEn() == true)
            {
              if ((RfidGetAllowedToOpenDoubleLock() != true) &&
                  (pCardInfomationIn->CardFunction.ControlBit.Recover != true))
              {
                ValidityResult = false;
              }
            }

            if (ValidityResult == true)
            {
              RfidUpdateReplaceInformation(pCardInfomationIn->CardFunction.ControlBit.Replace, pCardInfomationIn->StartTimestamp, pCardInfomationIn->ReplaceId, RFID_NORMAL_OPEN_CARD);

              bool NormalOpenEn = (RfidDetermineWhetherItIsInTheNormallyOpenState() != true) ? true : false;
              RfidHintAuthenticationSuccessHanlder(RFID_NORMAL_OPEN_CARD, pCardInfomationIn->CardSerialNumber, NormalOpenEn);
            }
            else
            {
              PRINT("[rfid]: equipment anti-lock.\r\n");

              RfidHintAntiLockHandler();
            }
          }
          else
          {
            PRINT("[rfid]: replace info error.\r\n");

            (ReplaceErrorCode == RFID_PROTOCOL_ID_ERROR) ? RfidHintCardRepaceErrorHandler() : RfidHintCardOutOfDateHanlder();
          }
        }
        else
        {
          PRINT("[rfid]: failure to verify room information.\r\n");
          RfidCardAffiliationErrorHanlder();
        }
      }
      else
      {
        PRINT("[rfid]: time verification failed.\r\n");

        RfidHintCardOutOfDateHanlder();
      }
    }
    else
    {
      PRINT("[rfid]: master normal open card is not enabled.\r\n");
      RfidThisFunctionCardHasBeenDisabledHanlder();
    }
  }
}

bool RunningClearCardFunction(uint8_t *CardSerialNumber)
{
  PRINT("[rfid] : RunningClearCardFunction \r\n");
  if (CardSerialNumber != NULL)
  {
    RfidDeleteAllLoGInformation();
    RfidStartDeviceFactorySetting();
    RfidWriteClearParameterCardNumberLog(CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);
    return true;
  }
  return false;
}

static bool RfidPraseResetCardData(RfidProtocolFormat_t *pCardInfomationIn)
{
  uint32_t *pRatedNumberOfUses = NULL, *pNumberOfTimesUsed = NULL;

  if (pCardInfomationIn != NULL)
  {
    pNumberOfTimesUsed = &pCardInfomationIn->EndTimestamp;
    pRatedNumberOfUses = &pCardInfomationIn->StartTimestamp;

    if ((pNumberOfTimesUsed != NULL) && (pRatedNumberOfUses != NULL))
    {
      if (pRatedNumberOfUses > 0)
      {
        if (pNumberOfTimesUsed < pRatedNumberOfUses)
        {
          pNumberOfTimesUsed++;

          RfidDeleteAllLoGInformation();
          RfidStartDeviceFactorySetting();
          RfidWriteClearParameterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHENTICATION_SUCCESS);

          return true;
        }
      }
    }
  }

  RfidWriteClearParameterCardNumberLog(pCardInfomationIn->CardSerialNumber, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER, OFFLINE_CARD_AUTHECTICATION_ERROR);

  return false;
}

bool RfidValidateCardDataValidity(const uint8_t *pDataIn, const uint8_t *pCardSerialNumberIn, uint8_t CardProtocol)
{
  uint8_t *pDataPacket = (uint8_t *)pDataIn;
  RfidProtocolFormat_t RfidProtocolFormat = {0};

  if ((pDataPacket != NULL) && (pCardSerialNumberIn != NULL))
  {
    memcpy(RfidProtocolFormat.CardSerialNumber, pCardSerialNumberIn, RFID_NUMBER_OF_MIFARE_CARD_SERIAL_NUMBER);

    // step1: 判断长度是否有效
    {
      RfidProtocolFormat.Length = *pDataPacket++ << 8;
      RfidProtocolFormat.Length |= *pDataPacket++;
      if ((RfidProtocolFormat.Length == 0) || (RfidProtocolFormat.Length > RFID_MAX_LENGTH_OF_OPERATION_DATA))
      {
        PRINT("[rfid]: card length is valid.\r\n");
        return false;
      }
    }

    // step2: 计算 CRC 校验值
    {
      uint8_t CrcCheckValue = 0;

      switch (CardProtocol)
      {
      case RFID_CARD_PROTOCOL_HZ:
        CrcCheckValue = RfidCalculateXorValue(pDataIn, RfidProtocolFormat.Length - 1);
        break;

      default:
        CrcCheckValue = RfidCalculateSumCheck(pDataIn, RfidProtocolFormat.Length - 1);
        break;
      }

      if (CrcCheckValue != pDataIn[RfidProtocolFormat.Length - 1])
      {
        PRINT("[rfid]: abnormal check data, crc value: %02X, agreement: %02X.\r\n", CrcCheckValue, pDataIn[RfidProtocolFormat.Length - 1]);
        return false;
      }
    }

    // step3: 从随机数到校验位前的数据进行AES解密
    {
      uint16_t DecryptDataLength = RfidProtocolFormat.Length - 3;

      if ((DecryptDataLength % 16) != 0)
      {
        PRINT("[rfid]: error in the length of data to be decrypted.\r\n");
        return false;
      }

      // AES 解密
      {
        uint8_t *pDataBuffOffset = pDataPacket;
        uint8_t SectorKeyValue[ENCRYPTION_KEY_LENGTH + 1] = {0};

        // 获取扇区访问密钥
        {
          RfidGetSectorAccessKey(SectorKeyValue);
          switch (CardProtocol)
          {
          case RFID_CARD_PROTOCOL_HZ:
            memcpy(&SectorKeyValue[CRAD_SECTOR_KEY_LENGTH], OFFLINE_CARD_KEY_SUFFIX_HZ, strlen(OFFLINE_CARD_KEY_SUFFIX_HZ));
            break;

          default:
            memcpy(&SectorKeyValue[CRAD_SECTOR_KEY_LENGTH], OFFLINE_CARD_KEY_SUFFIX_YG, strlen(OFFLINE_CARD_KEY_SUFFIX_YG));
            break;
          }
        }

        for (uint8_t i = 0; i < DecryptDataLength / 16; i++)
        {
          RfidAesEcbDecrypt(SectorKeyValue, pDataBuffOffset, pDataBuffOffset);
          pDataBuffOffset += 16;
        }
      }
    }

    // step4: 用随机数对验证码到校验位前的数据进行异或解密
    {
      memcpy(RfidProtocolFormat.Random, pDataPacket, OFFLINE_CARD_RANDOM_BIT_LENGTH);
      pDataPacket += OFFLINE_CARD_RANDOM_BIT_LENGTH;
      RfidCalXorDecrypt(RfidProtocolFormat.Random, OFFLINE_CARD_RANDOM_BIT_LENGTH, pDataPacket, (RfidProtocolFormat.Length - OFFLINE_CARD_RANDOM_BIT_LENGTH - 3));
    }

    // step5: 校验验证码是否正确
    {
      bool CaptchaCheckResult = false;

      memcpy(RfidProtocolFormat.Captcha, pDataPacket, OFFLINE_CARD_CAPTCHA_BIT_LENGTH);
      pDataPacket += OFFLINE_CARD_CAPTCHA_BIT_LENGTH;

      switch (CardProtocol)
      {
      case RFID_CARD_PROTOCOL_HZ:
      {
        if (memcmp(RfidProtocolFormat.Captcha, OFFLINE_CARD_CAPTCHA_DATA_HZ, OFFLINE_CARD_CAPTCHA_BIT_LENGTH) == 0)
        {
          CaptchaCheckResult = true;
        }
      }
      break;

      default:
      {
        if (memcmp(RfidProtocolFormat.Captcha, OFFLINE_CARD_CAPTCHA_DATA_YG, OFFLINE_CARD_CAPTCHA_BIT_LENGTH) == 0)
        {
          CaptchaCheckResult = true;
        }
      }
      break;
      }

      if (CaptchaCheckResult != true)
      {
        PRINT("[rfid]: captcha error.\r\n");
        return false;
      }
    }

    // step6: 判断卡类型是否有效
    {
      RfidProtocolFormat.CardType = *pDataPacket++;
      if (RfidVerifyCardTypeIsValid(RfidProtocolFormat.CardType) != true)
      {
        PRINT("[rfid]: unknown card type.\r\n");
        return false;
      }
    }

    // step7: 获取顶替号
    {
      RfidProtocolFormat.ReplaceId = *pDataPacket++ << 8;
      RfidProtocolFormat.ReplaceId |= *pDataPacket++;
    }

    // step8: 获取类别号
    {
      RfidProtocolFormat.TranslationCategory = *pDataPacket++ << 8;
      RfidProtocolFormat.TranslationCategory |= *pDataPacket++;
    }

    // step9: 获取分组号
    {
      RfidProtocolFormat.Grouping = *pDataPacket++ << 24;
      RfidProtocolFormat.Grouping |= *pDataPacket++ << 16;
      RfidProtocolFormat.Grouping |= *pDataPacket++ << 8;
      RfidProtocolFormat.Grouping |= *pDataPacket++;

      RfidProtocolFormat.Reserved = *pDataPacket++ << 24;
      RfidProtocolFormat.Reserved |= *pDataPacket++ << 16;
      RfidProtocolFormat.Reserved |= *pDataPacket++ << 8;
      RfidProtocolFormat.Reserved |= *pDataPacket++;
    }

    // step10: 获取授权信息
    {
      // 获取授权时间
      {
        RfidProtocolFormat.StartTimestamp = *pDataPacket++ << 24;
        RfidProtocolFormat.StartTimestamp |= *pDataPacket++ << 16;
        RfidProtocolFormat.StartTimestamp |= *pDataPacket++ << 8;
        RfidProtocolFormat.StartTimestamp |= *pDataPacket++;
        RfidProtocolFormat.EndTimestamp = *pDataPacket++ << 24;
        RfidProtocolFormat.EndTimestamp |= *pDataPacket++ << 16;
        RfidProtocolFormat.EndTimestamp |= *pDataPacket++ << 8;
        RfidProtocolFormat.EndTimestamp |= *pDataPacket++;
        RfidProtocolFormat.Date = *pDataPacket++;
      }

      // 获取授权时间段
      {
        RfidProtocolFormat.NumberOfTimeSlots = *pDataPacket++;
        if (RfidProtocolFormat.NumberOfTimeSlots > OFFLINE_CARD_MAX_TIME_SLOTS)
        {
          PRINT("[rfid]: exceeding time slots limit.\r\n");
          return false;
        }

        for (uint8_t i = 0; i < RfidProtocolFormat.NumberOfTimeSlots; i++)
        {
          RfidProtocolFormat.Time[i].TimeCycle.StartHour = *pDataPacket++;
          RfidProtocolFormat.Time[i].TimeCycle.StartMinute = *pDataPacket++;
          RfidProtocolFormat.Time[i].TimeCycle.EndHour = *pDataPacket++;
          RfidProtocolFormat.Time[i].TimeCycle.EndMinute = *pDataPacket++;
        }
      }

      // 获取卡片功能
      {
        RfidProtocolFormat.CardFunction.Ident = *pDataPacket++;
      }
    }

    // step11: 获取房间信息
    {
      RfidProtocolFormat.NumberOfRoom = *pDataPacket++;
      if ((RfidProtocolFormat.NumberOfRoom == VIRTUAL_CARD_SERIAL_NUMBER_LENGTH) && (RfidProtocolFormat.CardType == RFID_VIRTUAL_CARD_SERIAL_NUMBER))
      {
        memcpy(RfidProtocolFormat.CardSerialNumber, pDataPacket, VIRTUAL_CARD_SERIAL_NUMBER_LENGTH);
        pDataPacket += VIRTUAL_CARD_SERIAL_NUMBER_LENGTH;
      }
      else
      {
        if (RfidProtocolFormat.NumberOfRoom > OFFLINE_CARD_MAX_ROOM_QUANTITIES)
        {
          PRINT("[rfid]: exceeding room limit.\r\n");
          return false;
        }

        for (uint8_t i = 0; i < RfidProtocolFormat.NumberOfRoom; i++)
        {
          RfidProtocolFormat.RoomId[i].GardenId = *pDataPacket++;
          RfidProtocolFormat.RoomId[i].BuildId = *pDataPacket++;
          RfidProtocolFormat.RoomId[i].FloorId = *pDataPacket++;
          RfidProtocolFormat.RoomId[i].RoomId = *pDataPacket++ << 24;
          RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++ << 16;
          RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++ << 8;
          RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++;
          RfidProtocolFormat.RoomId[i].SubroomId = *pDataPacket++;
        }
      }
    }

    // step12: 执行离线卡相关动作
    {
      if (OfflineCardPrase[RfidProtocolFormat.CardType] != NULL)
      {
        OfflineCardPrase[RfidProtocolFormat.CardType](&RfidProtocolFormat);
      }
    }
  }

  return true;
}

bool RfidVerifyCardDataValidity(const uint8_t *pDataIn, uint16_t DataSize, uint8_t *pDataOut, uint16_t *pSizeOut)
{
  uint8_t *pDataPacket = (uint8_t *)pDataIn;
  RfidProtocolFormat_t RfidProtocolFormat = {0};

  if (pDataPacket != NULL)
  {
    // step1: 判断长度是否有效
    {
      RfidProtocolFormat.Length = *pDataPacket++ << 8;
      RfidProtocolFormat.Length |= *pDataPacket++;
      if ((RfidProtocolFormat.Length == 0) || (RfidProtocolFormat.Length > RFID_MAX_LENGTH_OF_OPERATION_DATA))
      {
        PRINT("[rfid]: card length is valid.\r\n");
        return false;
      }
    }

    // step2: 计算 CRC 校验值
    {
      uint8_t CrcCheckValue = RfidCalculateSumCheck(pDataIn, RfidProtocolFormat.Length - 1);

      if (CrcCheckValue != pDataIn[RfidProtocolFormat.Length - 1])
      {
        PRINT("[rfid]: abnormal check data, crc value: %02X, agreement: %02X.\r\n", CrcCheckValue, pDataIn[RfidProtocolFormat.Length - 1]);
        return false;
      }
    }

    // step3: 从随机数到校验位前的数据进行AES解密
    {
      uint16_t DecryptDataLength = RfidProtocolFormat.Length - 3;

      if ((DecryptDataLength % 16) != 0)
      {
        PRINT("[rfid]: error in the length of data to be decrypted.\r\n");
        return false;
      }

      // AES 解密
      {
        uint8_t *pDataBuffOffset = pDataPacket;
        uint8_t SectorKeyValue[ENCRYPTION_KEY_LENGTH + 1] = {0};

        memcpy(&SectorKeyValue[CRAD_SECTOR_KEY_LENGTH], OFFLINE_CARD_KEY_SUFFIX_YG, strlen(OFFLINE_CARD_KEY_SUFFIX_YG));

        for (uint8_t i = 0; i < DecryptDataLength / 16; i++)
        {
          RfidAesEcbDecrypt(SectorKeyValue, pDataBuffOffset, pDataBuffOffset);
          pDataBuffOffset += 16;
        }
      }

      // step4: 用随机数对验证码到校验位前的数据进行异或解密
      {
        memcpy(RfidProtocolFormat.Random, pDataPacket, OFFLINE_CARD_RANDOM_BIT_LENGTH);
        pDataPacket += OFFLINE_CARD_RANDOM_BIT_LENGTH;
        RfidCalXorDecrypt(RfidProtocolFormat.Random, OFFLINE_CARD_RANDOM_BIT_LENGTH, pDataPacket, (RfidProtocolFormat.Length - OFFLINE_CARD_RANDOM_BIT_LENGTH - 3));
      }

      // step5: 校验验证码是否正确
      {
        bool CaptchaCheckResult = false;

        memcpy(RfidProtocolFormat.Captcha, pDataPacket, OFFLINE_CARD_CAPTCHA_BIT_LENGTH);
        pDataPacket += OFFLINE_CARD_CAPTCHA_BIT_LENGTH;

        if (memcmp(RfidProtocolFormat.Captcha, OFFLINE_CARD_CAPTCHA_DATA_YG, OFFLINE_CARD_CAPTCHA_BIT_LENGTH) == 0)
        {
          CaptchaCheckResult = true;
        }

        if (CaptchaCheckResult != true)
        {
          PRINT("[rfid]: captcha error.\r\n");
          return false;
        }
      }

      // step6: 判断卡类型是否有效
      {
        RfidProtocolFormat.CardType = *pDataPacket++;
        if (RfidProtocolFormat.CardType != RFID_CLEAR_CARD)
        {
          PRINT("[rfid]: card type false.\r\n");
          return false;
        }
      }

      // step7: 获取顶替号
      {
        RfidProtocolFormat.ReplaceId = *pDataPacket++ << 8;
        RfidProtocolFormat.ReplaceId |= *pDataPacket++;
      }

      // step8: 获取类别号
      {
        RfidProtocolFormat.TranslationCategory = *pDataPacket++ << 8;
        RfidProtocolFormat.TranslationCategory |= *pDataPacket++;
      }

      // step9: 获取分组号
      {
        RfidProtocolFormat.Grouping = *pDataPacket++ << 24;
        RfidProtocolFormat.Grouping |= *pDataPacket++ << 16;
        RfidProtocolFormat.Grouping |= *pDataPacket++ << 8;
        RfidProtocolFormat.Grouping |= *pDataPacket++;

        RfidProtocolFormat.Reserved = *pDataPacket++ << 24;
        RfidProtocolFormat.Reserved |= *pDataPacket++ << 16;
        RfidProtocolFormat.Reserved |= *pDataPacket++ << 8;
        RfidProtocolFormat.Reserved |= *pDataPacket++;
      }

      // step10: 获取授权信息
      {
        // 获取授权时间
        {
          RfidProtocolFormat.StartTimestamp = *pDataPacket++ << 24;
          RfidProtocolFormat.StartTimestamp |= *pDataPacket++ << 16;
          RfidProtocolFormat.StartTimestamp |= *pDataPacket++ << 8;
          RfidProtocolFormat.StartTimestamp |= *pDataPacket++;
          RfidProtocolFormat.EndTimestamp = *pDataPacket++ << 24;
          RfidProtocolFormat.EndTimestamp |= *pDataPacket++ << 16;
          RfidProtocolFormat.EndTimestamp |= *pDataPacket++ << 8;
          RfidProtocolFormat.EndTimestamp |= *pDataPacket++;
          RfidProtocolFormat.Date = *pDataPacket++;
        }

        // 获取授权时间段
        {
          RfidProtocolFormat.NumberOfTimeSlots = *pDataPacket++;
          if (RfidProtocolFormat.NumberOfTimeSlots > OFFLINE_CARD_MAX_TIME_SLOTS)
          {
            PRINT("[rfid]: exceeding time slots limit.\r\n");
            return false;
          }

          for (uint8_t i = 0; i < RfidProtocolFormat.NumberOfTimeSlots; i++)
          {
            RfidProtocolFormat.Time[i].TimeCycle.StartHour = *pDataPacket++;
            RfidProtocolFormat.Time[i].TimeCycle.StartMinute = *pDataPacket++;
            RfidProtocolFormat.Time[i].TimeCycle.EndHour = *pDataPacket++;
            RfidProtocolFormat.Time[i].TimeCycle.EndMinute = *pDataPacket++;
          }
        }

        // 获取卡片功能
        {
          RfidProtocolFormat.CardFunction.Ident = *pDataPacket++;
        }
      }

      // step11: 获取房间信息
      {
        RfidProtocolFormat.NumberOfRoom = *pDataPacket++;
        if ((RfidProtocolFormat.NumberOfRoom == VIRTUAL_CARD_SERIAL_NUMBER_LENGTH) && (RfidProtocolFormat.CardType == RFID_VIRTUAL_CARD_SERIAL_NUMBER))
        {
          memcpy(RfidProtocolFormat.CardSerialNumber, pDataPacket, VIRTUAL_CARD_SERIAL_NUMBER_LENGTH);
          pDataPacket += VIRTUAL_CARD_SERIAL_NUMBER_LENGTH;
        }
        else
        {
          if (RfidProtocolFormat.NumberOfRoom > OFFLINE_CARD_MAX_ROOM_QUANTITIES)
          {
            PRINT("[rfid]: exceeding room limit.\r\n");
            return false;
          }

          for (uint8_t i = 0; i < RfidProtocolFormat.NumberOfRoom; i++)
          {
            RfidProtocolFormat.RoomId[i].GardenId = *pDataPacket++;
            RfidProtocolFormat.RoomId[i].BuildId = *pDataPacket++;
            RfidProtocolFormat.RoomId[i].FloorId = *pDataPacket++;
            RfidProtocolFormat.RoomId[i].RoomId = *pDataPacket++ << 24;
            RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++ << 16;
            RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++ << 8;
            RfidProtocolFormat.RoomId[i].RoomId |= *pDataPacket++;
            RfidProtocolFormat.RoomId[i].SubroomId = *pDataPacket++;
          }
        }
      }

      // step12: 执行离线卡数据更新相关动作
      {
        if (OfflineCardDataUpdate[RfidProtocolFormat.CardType] != NULL)
        {
          if (OfflineCardDataUpdate[RfidProtocolFormat.CardType](&RfidProtocolFormat) != true)
            return false;
        }

        if (pDataOut != NULL)
        {
          if (RfidRefactorOfflineCardData(&RfidProtocolFormat, pDataOut, pSizeOut) != true)
            return false;
        }
      }
    }
  }

  return true;
}
#endif
